package com.cskaoyan.wordmemorize.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cskaoyan.wordmemorize.common.annotation.OperateLog;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.converter.LevelConverter;
import com.cskaoyan.wordmemorize.dao.entity.LevelPrivilegeDO;
import com.cskaoyan.wordmemorize.dao.mapper.LevelPrivilegeMapper;
import com.cskaoyan.wordmemorize.dto.admin.DeleteLevelPrivilegeOperateDTO;
import com.cskaoyan.wordmemorize.dto.admin.LevelPrivilegeDTO;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.request.BatchDeleteCommand;
import com.cskaoyan.wordmemorize.request.LevelPrivilegeCommand;
import com.cskaoyan.wordmemorize.request.LevelPrivilegePageRequest;
import com.cskaoyan.wordmemorize.service.LevelPrivilegeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 等级特权服务实现类
 */
@Service
@Slf4j
public class LevelPrivilegeServiceImpl extends ServiceImpl<LevelPrivilegeMapper, LevelPrivilegeDO> implements LevelPrivilegeService {

    @Autowired
    private LevelConverter levelConverter;

    /**
     * 分页查询(后台等级权限管理-特权管理)
     *
     * @param pageRequest 分页请求
     * @return 分页结果
     */
    @Override
    public PageDTO<LevelPrivilegeDTO> getLevelPrivilegeList(LevelPrivilegePageRequest pageRequest) {
        // 构建查询条件
        LambdaQueryWrapper<LevelPrivilegeDO> queryWrapper = new LambdaQueryWrapper<>();

        // 如果有关键词，则添加模糊查询条件——特权名/特权码
        if (StringUtils.hasText(pageRequest.getKeyword())) {
            queryWrapper.like(LevelPrivilegeDO::getPrivilegeName, pageRequest.getKeyword())
                    .or()
                    .like(LevelPrivilegeDO::getPrivilegeCode, pageRequest.getKeyword());
        }

        // 如果有等级ID，按等级ID查询
        if (StringUtils.hasText(pageRequest.getLevelId())) {
            queryWrapper.eq(LevelPrivilegeDO::getLevelId, Long.valueOf(pageRequest.getLevelId()));
        }

        // 只查询未删除的记录
        queryWrapper.eq(LevelPrivilegeDO::getIsDeleted, 0);

        // 分页查询
        Page<LevelPrivilegeDO> page = new Page<>(
                pageRequest.getPageNum() != null ? pageRequest.getPageNum() : 1,
                pageRequest.getCount() != null ? pageRequest.getCount() : 10
        );

        Page<LevelPrivilegeDO> resultPage = page(page, queryWrapper);

        // 转换为DTO并返回

        return levelConverter.levelPrivilegeDOToPageDTO(resultPage.getRecords(), (int) resultPage.getTotal());
    }

    /**
     * 添加等级特权(后台等级权限管理-特权管理)
     *
     * @param command 等级特权命令
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @OperateLog(dateType = "等级特权", operateType = 1)
    public void addLevelPrivilege(LevelPrivilegeCommand command) {
        // 检查特权码是否已存在
        LambdaQueryWrapper<LevelPrivilegeDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LevelPrivilegeDO::getPrivilegeCode, command.getPrivilegeCode())
                .eq(LevelPrivilegeDO::getIsDeleted, 0);

        if (count(queryWrapper) > 0) {
            throw new BusinessException("特权码已存在", ResultCodeEnum.FAIL.getCode());
        }

        // 转换为DO并保存
        LevelPrivilegeDO privilegeDO = levelConverter.levelPrivilegeCommandToLevelPrivilegeDO(command);

        // 保存记录
        boolean success = save(privilegeDO);

        if (!success) {
            throw new BusinessException(ResultCodeEnum.FAIL);
        }
    }

    /**
     * 更新等级特权(后台等级权限管理-特权管理)
     *
     * @param command 等级特权命令
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @OperateLog(dateType = "等级特权", operateType = 2)
    public void updateLevelPrivilege(LevelPrivilegeCommand command) {
        // 检查特权是否存在
        if (!StringUtils.hasText(command.getId())) {
            throw new BusinessException(ResultCodeEnum.PARAM_ERROR);
        }

        LevelPrivilegeDO existPrivilege = getById(Long.valueOf(command.getId()));
        if (existPrivilege == null || existPrivilege.getIsDeleted() == 1) {
            throw new BusinessException("特权不存在", ResultCodeEnum.FAIL.getCode());
        }

        // 检查特权码是否已被其他记录使用
        if (StringUtils.hasText(command.getPrivilegeCode()) && !command.getPrivilegeCode().equals(existPrivilege.getPrivilegeCode())) {
            LambdaQueryWrapper<LevelPrivilegeDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(LevelPrivilegeDO::getPrivilegeCode, command.getPrivilegeCode())
                    .eq(LevelPrivilegeDO::getIsDeleted, 0)
                    .ne(LevelPrivilegeDO::getId, Long.valueOf(command.getId()));

            if (count(queryWrapper) > 0) {
                throw new BusinessException("特权码已存在", ResultCodeEnum.FAIL.getCode());
            }
        }

        // 转换为DO并更新
        LevelPrivilegeDO privilegeDO = levelConverter.levelPrivilegeCommandToLevelPrivilegeDO(command);

        // 更新记录
        boolean success = updateById(privilegeDO);

        if (!success) {
            throw new BusinessException(ResultCodeEnum.FAIL);
        }
    }


    /**
     * 删除等级特权(后台等级权限管理-特权管理)
     *
     * @param id 特权ID
     * @return 删除操作日志
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @OperateLog(dateType = "等级特权", operateType = 3)
    public DeleteLevelPrivilegeOperateDTO deleteLevelPrivilege(Long id) {
        log.info("开始删除特权，ID: {}", id);

        // 检查特权是否存在
        LevelPrivilegeDO privilegeDO = getById(id);
        if (privilegeDO == null) {
            log.error("特权不存在，ID: {}", id);
            throw new BusinessException("特权不存在", ResultCodeEnum.FAIL.getCode());
        }

        if (privilegeDO.getIsDeleted() == 1) {
            log.error("特权已经被删除，ID: {}", id);
            throw new BusinessException("特权已经被删除", ResultCodeEnum.FAIL.getCode());
        }

        // 保存原始数据用于返回操作日志
        LevelPrivilegeDO originalDO = new LevelPrivilegeDO();
        BeanUtils.copyProperties(privilegeDO, originalDO);

        // 使用UpdateWrapper明确指定要更新的字段
        LambdaUpdateWrapper<LevelPrivilegeDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(LevelPrivilegeDO::getId, id)
                .set(LevelPrivilegeDO::getIsDeleted, 1);

        boolean success = update(null, updateWrapper);
        if (!success) {
            log.error("更新特权失败，ID: {}", id);
            throw new BusinessException("删除特权失败", ResultCodeEnum.FAIL.getCode());
        }

        log.info("特权删除成功，ID: {}", id);

        // 返回删除操作日志
        return levelConverter.levelPrivilegeDOToDeleteLevelPrivilegeOperateDTO(originalDO);
    }


    /**
     * 批量删除等级特权(后台等级权限管理-特权管理)
     *
     * @param command 批量删除命令
     * @return 删除操作日志列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @OperateLog(dateType = "等级特权", operateType = 4)
    public List<DeleteLevelPrivilegeOperateDTO> batchDeleteLevelPrivilege(BatchDeleteCommand command) {
        log.info("开始批量删除特权，IDs: {}", command.getIds());

        if (command.getIds() == null || command.getIds().isEmpty()) {
            log.warn("批量删除特权时ID列表为空");
            return new ArrayList<>();
        }

        // 将字符串ID转换为Long类型
        List<Long> privilegeIds = command.getIds().stream()
                .map(Long::valueOf)
                .collect(Collectors.toList());

        log.info("转换后的ID列表: {}", privilegeIds);

        // 查询要删除的特权（只查询未删除的记录）
        LambdaQueryWrapper<LevelPrivilegeDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(LevelPrivilegeDO::getId, privilegeIds)
                .eq(LevelPrivilegeDO::getIsDeleted, 0);

        List<LevelPrivilegeDO> privilegeDOList = list(queryWrapper);
        log.info("查询到的特权数量: {}", privilegeDOList.size());

        if (privilegeDOList.isEmpty()) {
            log.warn("没有找到需要删除的特权");
            return new ArrayList<>();
        }

        // 保存原始数据用于返回操作日志
        List<LevelPrivilegeDO> originalList = new ArrayList<>();
        for (LevelPrivilegeDO privilegeDO : privilegeDOList) {
            LevelPrivilegeDO originalDO = new LevelPrivilegeDO();
            BeanUtils.copyProperties(privilegeDO, originalDO);
            originalList.add(originalDO);
        }

        // 使用UpdateWrapper批量更新
        LambdaUpdateWrapper<LevelPrivilegeDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(LevelPrivilegeDO::getId, privilegeIds)
                .set(LevelPrivilegeDO::getIsDeleted, 1);

        boolean success = update(null, updateWrapper);
        log.info("批量删除结果: {}", success);

        if (!success) {
            log.error("批量删除特权失败");
            throw new BusinessException("批量删除特权失败", ResultCodeEnum.FAIL.getCode());
        }

        // 再次查询确认是否删除成功
        LambdaQueryWrapper<LevelPrivilegeDO> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.in(LevelPrivilegeDO::getId, privilegeIds)
                .eq(LevelPrivilegeDO::getIsDeleted, 0);

        long count = count(checkWrapper);
        if (count > 0) {
            log.error("有{}条记录未被成功删除", count);
            throw new BusinessException("部分特权删除失败", ResultCodeEnum.FAIL.getCode());
        }

        log.info("批量删除特权成功，共{}条", privilegeDOList.size());

        // 返回删除操作日志列表
        return levelConverter.levelPrivilegeDOsToDeleteLevelPrivilegeOperateDTOs(originalList);
    }
}
